From: Marco Trevisan (Treviño) Date: Fri, 31 Oct 2025 03:48:21 +0000 (+0100) Subject: workspaceThumbnail: Track later hiding drop placeholder X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~66^2^2~19 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=c1092d4b3e0cab3f89db8ba7636eedea184ddba8;p=gnome-shell.git workspaceThumbnail: Track later hiding drop placeholder When closing the shell during a relayout we are getting this error: (gnome-shell:2559407): Gjs-CRITICAL **: 06:57:21.765: Object St.Bin, has been already disposed — impossible to access it. This might be caused by the object having been destroyed from C code using something such as destroy(), dispose(), or remove() vfuncs. == Stack trace for context 0x60991609b710 == #0 b resource:///org/gnome/shell/ui/workspaceThumbnail.js:1334 (5e050636fb0 @ 17) #1 i resource:///org/gnome/shell/ui/main.js:279 (30c932d102e0 @ 119) This is because the later we added is running even when not needed (e.g when the placeholder is not visible already), but also because we may run the later callback after the parent has been destroyed. Prevent this to happen, by tracking the later Part-of: (cherry picked from commit 60a071052a0e547e813c6da6db8b4fc8d3149398) --- diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js index 34feaa1af..1ccabd5e7 100644 --- a/js/ui/workspaceThumbnail.js +++ b/js/ui/workspaceThumbnail.js @@ -688,6 +688,7 @@ export const ThumbnailsBox = GObject.registerClass({ _onDestroy() { this._destroyThumbnails(); this._unqueueUpdateStates(); + this._clearDropPlaceholderLater(); if (this._settings) this._settings.run_dispose(); @@ -769,6 +770,14 @@ export const ThumbnailsBox = GObject.registerClass({ this.queue_relayout(); } + _clearDropPlaceholderLater() { + if (!this._dropPlaceholderLater) + return; + + global.compositor.get_laters().remove(this._dropPlaceholderLater); + delete this._dropPlaceholderLater; + } + _getPlaceholderTarget(index, spacing, rtl) { const workspace = this._thumbnails[index]; @@ -1329,10 +1338,15 @@ export const ThumbnailsBox = GObject.registerClass({ this._dropPlaceholder.allocate_preferred_size( ...this._dropPlaceholder.get_position()); - const laters = global.compositor.get_laters(); - laters.add(Meta.LaterType.BEFORE_REDRAW, () => { - this._dropPlaceholder.hide(); - }); + this._clearDropPlaceholderLater(); + if (this._dropPlaceholder.visible) { + const laters = global.compositor.get_laters(); + this._dropPlaceholderLater = laters.add( + Meta.LaterType.BEFORE_REDRAW, () => { + this._dropPlaceholder.hide(); + delete this._dropPlaceholderLater; + }); + } } let childBox = new Clutter.ActorBox(); @@ -1360,10 +1374,15 @@ export const ThumbnailsBox = GObject.registerClass({ this._dropPlaceholder.allocate(childBox); - const laters = global.compositor.get_laters(); - laters.add(Meta.LaterType.BEFORE_REDRAW, () => { - this._dropPlaceholder.show(); - }); + this._clearDropPlaceholderLater(); + if (!this._dropPlaceholder.visible) { + const laters = global.compositor.get_laters(); + this._dropPlaceholderLater = laters.add( + Meta.LaterType.BEFORE_REDRAW, () => { + this._dropPlaceholder.show(); + delete this._dropPlaceholderLater; + }); + } x += placeholderWidth + spacing; }